package com.wu.flandre.component.aop;

import com.wu.flandre.annotation.ApiCensus;
import com.wu.flandre.component.MsgRecord;
import com.wu.flandre.entity.common.ApiCallMsgRecordEntity;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;

import java.lang.reflect.Method;

/**
 * AnnotationAop <br/>
 *
 * @author 50816 <br/>
 * @date 2019/12/13 23:40 <br/>
 */
@Aspect
@Component
@Slf4j
public class ApiCallCensusAop {

    @Autowired
    private MsgRecord msgRecord;

    @Pointcut("@annotation(com.wu.flandre.annotation.ApiCensus)")
    public void apiCensus() {
    }

    @Around("apiCensus()")
    public Object Interceptor(ProceedingJoinPoint joinPoint) {
        Object obj = null;
        Object[] args = joinPoint.getArgs();
        long startTime = System.currentTimeMillis();
        try {
            obj = joinPoint.proceed(args);
        } catch (Throwable e) {
            log.error("统计Api调用信息环绕通知出错", e);
        }
        // 获取执行的方法名
        long endTime = System.currentTimeMillis();
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        Method method = signature.getMethod();
        ApiCensus apiCemsus = signature.getMethod().getAnnotation(ApiCensus.class);

        String apiPath = null;
        if (method.isAnnotationPresent(GetMapping.class)) {
            apiPath = method.getAnnotation(GetMapping.class).value()[0];
        } else if (method.isAnnotationPresent(PostMapping.class)) {
            apiPath = method.getAnnotation(PostMapping.class).value()[0];
        } else if (method.isAnnotationPresent(PutMapping.class)) {
            apiPath = method.getAnnotation(PutMapping.class).value()[0];
        } else if (method.isAnnotationPresent(DeleteMapping.class)) {
            apiPath = method.getAnnotation(DeleteMapping.class).value()[0];
        } else {
            apiPath = "unknown path";
        }

        String apiName = apiCemsus.apiName();
        String methodName = signature.getDeclaringTypeName() + "." + signature.getName();
        ApiCallMsgRecordEntity recordEntity = new ApiCallMsgRecordEntity(apiName, methodName, apiPath, startTime, endTime);
        msgRecord.apiCallMsgRecord(recordEntity);
        return obj;
    }

}
